# -*- coding: utf-8 -*-
# Created by huagnqiyin on 2016/8/24

import aioredis
import asyncio
import logging


class AioRedisPool(object):
    # Store connection pool by cache backend options.
    # _pools is a process-global
    _pools = {}

    def __init__(self):
        super(object, self).__init__()
        self._log = logging.getLogger("redis")

    @staticmethod
    def reset_pool():
        if AioRedisPool._pools:
            AioRedisPool._pools.clear()

    @staticmethod
    async def close_pool():
        for key in AioRedisPool._pools:
            pool = AioRedisPool._pools[key]
            await pool.wait_closed()

    async def get_connection_from_pool(self, **kwargs):
        """
        Given a connection parameters and return a new
        or cached connection pool for them.
        """
        ip = kwargs["ip"]
        port = kwargs["port"]
        db = kwargs["db"]
        password = kwargs["password"]
        key = (ip, port, db)
        if key in AioRedisPool._pools:
            return AioRedisPool._pools[key]
        lock = asyncio.Lock()
        for i in range(5):
            try:
                await lock
                AioRedisPool._pools[key] = await aioredis.create_pool((ip, port), db=db, password=password, maxsize=20)
            except Exception as e:
                self._log.exception(e)
                pass
            else:
                return AioRedisPool._pools[key]
            finally:
                lock.release()
            self._log.fatal("create redis pool failed ip %s port %s count %d", ip, port, i)
            asyncio.sleep(1)
